/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;

namespace DaveSexton.DocProject
{
	[Serializable]
	public struct Source : IEquatable<Source>, IComparable, IComparable<Source>
	{
		#region Public Properties
		public static readonly Source Empty = new Source();

		public SystemPath Input
		{
			get
			{
				return input;
			}
		}

		public SystemPath XmlDocumentation
		{
			get
			{
				return xmlDocumentation;
			}
		}
		#endregion

		#region Private / Protected
		private readonly SystemPath input, xmlDocumentation;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="Source" /> structure.
		/// </summary>
		public Source(SystemPath input, SystemPath xmlDocumentation)
		{
			if (input == SystemPath.Empty)
				throw new ArgumentException(Resources.Errors.EmptySystemPathIsInvalid, "input");
			
			this.input = input;
			this.xmlDocumentation = xmlDocumentation;
		}
		#endregion

		#region Methods
		public bool HasChangedSince(DateTime dateTime, IEnumerable<string> inputFileExtensions)
		{
			if (input.IsAbsoluteFile)
			{
				if (input.HasChangedSince(dateTime))
					return true;
			}
			else if (input != SystemPath.Empty)
			{
				foreach (string extension in inputFileExtensions)
					if (input.HasChangedSince(dateTime, "*" + extension, input.HasRecursiveDirectory, false))
						return true;
			}

			if (xmlDocumentation.IsAbsoluteFile)
			{
				if (xmlDocumentation.HasChangedSince(dateTime))
					return true;
			}
			else if (xmlDocumentation != SystemPath.Empty)
			{
				if (xmlDocumentation.HasChangedSince(dateTime, "*.xml", xmlDocumentation.HasRecursiveDirectory, false))
					return true;
			}

			return false;
		}

		public override int GetHashCode()
		{
			return input.GetHashCode();
		}

		public override bool Equals(object obj)
		{
			return obj is Source && Equals((Source) obj);
		}

		public bool Equals(Source other)
		{
			return input.Equals(other.input);
		}

		public static bool operator ==(Source source1, Source source2)
		{
			return source1.Equals(source2);
		}

		public static bool operator !=(Source source1, Source source2)
		{
			return !source1.Equals(source2);
		}

		public static bool operator >(Source source1, Source source2)
		{
			return source1.CompareTo(source2) > 0;
		}

		public static bool operator <(Source source1, Source source2)
		{
			return source1.CompareTo(source2) < 0;
		}

		public override string ToString()
		{
			return "{" + input.Path + ", " + xmlDocumentation.Path + "}";
		}

		public int CompareTo(object obj)
		{
			return (obj is Source) ? CompareTo((Source) obj) : Comparer<object>.Default.Compare(this, obj);
		}

		public int CompareTo(Source other)
		{
			return input.CompareTo(other.input);
		}
		#endregion
	}
}
